package com.example.jetpackcomposestate.todo

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.FastOutLinearInEasing
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.TweenSpec
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp

/**
 * @author huangzehui
 * @date 3/5/2024 下午10:18 周五
 * @description
 *
 * https://www.bilibili.com/video/BV1ob4y1a7ad/?p=33&spm_id_from=pageDriver&vd_source=e07cc8cc94eb22bd76722071b03cd199
 */

// 顶部输入框加上一个灰色背景
@Composable
fun TodoItemInputBackground(
    elevate: Boolean,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    // 帧动画的形式展现Surface底部的阴影
    val animatedElevation by animateDpAsState(
        targetValue = if (elevate) 1.dp else 0.dp,
        TweenSpec(durationMillis = 500), label = ""
    )

    Surface(
        color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f),
        shadowElevation = animatedElevation,
        shape = RectangleShape
    ) {
        Row(
            modifier = modifier.animateContentSize(animationSpec = TweenSpec(durationMillis = 500)),
            content = content
        )
    }
}

// 输入框
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun TodoInputText(
    text: String,
    onTextChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    onItemAction: () -> Unit = {}
) {

    val keyboardController = LocalSoftwareKeyboardController.current

    TextField(
        value = text,
        onValueChange = onTextChange,
        colors = TextFieldDefaults.colors(
            focusedContainerColor = Color.Transparent, // 输入框获取焦点时候的容器颜色
            unfocusedContainerColor = Color.Transparent, // 输入框时区焦点时候的容器颜色
        ),
        maxLines = 1,
        modifier = modifier,
        keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done),
        keyboardActions = KeyboardActions(onDone = {
            onItemAction()
            keyboardController?.hide()
        })
    )
}

// 按钮
@Composable
fun TodoEditButton(
    onClick: () -> Unit,
    text: String,
    modifier: Modifier = Modifier,
    enabled: Boolean = true
) {
    TextButton(
        onClick = onClick,
        shape = CircleShape,
        colors = ButtonDefaults.buttonColors(),
        modifier = modifier,
        enabled = enabled
    ) {
        Text(text = text)
    }
}

/**
 * 一排图标，根据文本框是否有内容，自动收起和弹出，带动画效果
 *
 * https://www.bilibili.com/video/BV1ob4y1a7ad/?p=36&spm_id_from=pageDriver&vd_source=e07cc8cc94eb22bd76722071b03cd199
 */
@Composable
fun AnimatedIconRow(
    icon: TodoIcon,
    onIconChange: (TodoIcon) -> Unit,
    modifier: Modifier = Modifier,
    visible: Boolean = true
) {

    val enter = remember {
        fadeIn(animationSpec = TweenSpec(300, easing = FastOutLinearInEasing))
    }

    val exit = remember {
        fadeOut(animationSpec = TweenSpec(100, easing = FastOutSlowInEasing))
    }

    Box(modifier = modifier.defaultMinSize(minHeight = 16.dp)) {
        AnimatedVisibility(visible = visible, enter = enter, exit = exit) {
            IconRow(icon = icon, onIconChange = onIconChange)
        }
    }
}

@Composable
fun IconRow(
    icon: TodoIcon,
    onIconChange: (TodoIcon) -> Unit,
    modifier: Modifier = Modifier
) {
    Row(modifier = modifier) {
        for (todoIcon in TodoIcon.values()) {
            SelectableIconButton(
                icon = todoIcon.imageVector,
                iconContentDescription = todoIcon.contentDescription,
                onIconSelected = { onIconChange(todoIcon) },
                isSelected = todoIcon == icon
            )
        }
    }
}

@Composable
fun SelectableIconButton(
    icon: ImageVector,
    iconContentDescription: Int,
    onIconSelected: () -> Unit,
    isSelected: Boolean,
    modifier: Modifier = Modifier
) {

    // 图标选中和未选中状态，颜色不一样
    val tint = if (isSelected) {
        MaterialTheme.colorScheme.primary
    } else {
        MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
    }

    TextButton(
        onClick = { onIconSelected() },
        shape = CircleShape,
        modifier = modifier
    ) {
        Column {
            Icon(
                imageVector = icon,
                tint = tint,
                contentDescription = stringResource(id = iconContentDescription)
            )

            if (isSelected) {
                Box(
                    modifier = Modifier
                        .padding(top = 3.dp)
                        .width(icon.defaultWidth)
                        .height(1.dp)
                        .background(tint)
                )
            } else {
                Spacer(modifier = Modifier.height(4.dp))
            }
        }
    }
}

@Composable
fun TodoItemEntryInput(onItemComplete: (TodoItem) -> Unit) {
    val (text, setText) = remember {
        mutableStateOf("")
    }
    val (icon, setIcon) = remember {
        mutableStateOf(TodoIcon.DEFAULT)
    }
    val iconsVisible = text.isNotBlank()

    // 点击"Add"按钮，提交要做的事情
    val submit = {
        onItemComplete(
            TodoItem(
                task = text,
                icon = icon,
            )
        )

        setIcon(TodoIcon.DEFAULT)

        setText("")

    }

    TodoItemInput(
        text = text,
        onTextChange = setText,
        icon = icon,
        onIconChange = setIcon,
        submit = submit,
        iconsVisible = iconsVisible,
    )
}

@Composable
fun TodoItemInput(
    text: String,
    onTextChange: (String) -> Unit,
    icon: TodoIcon,
    onIconChange: (TodoIcon) -> Unit,
    submit: () -> Unit,
    iconsVisible: Boolean
) {
    /**
     * 这个函数使用remember给自己添加内存，然后在内存中存储一个由 mutableStateOf 创建的MutableState<String>
     * 它是Compose 的内置类型，提供了一个 可观察的状态持有者。
     * val (value, setValue) = remember { mutableStateOf (default) }
     * 对value的任何更改都将自动重新组合读取此状态的任何可组合函数。
     *
     */

//    val (text, setText) = remember {
//        mutableStateOf("")
//    }
//    val (icon, setIcon) = remember {
//        mutableStateOf(TodoIcon.DEFAULT)
//    }
//    val iconsVisible = text.isNotBlank()
//
//    // 点击"Add"按钮，提交要做的事情
//    val submit = {
//        onItemComplete(
//            TodoItem(
//                task = text,
//                icon = TodoIcon.Trash,
//            )
//        )
//
//        setIcon(TodoIcon.DEFAULT)
//
//        setText("")
//
//    }

    Column {
        Row(
            modifier = Modifier
                .padding(horizontal = 16.dp)
                .padding(top = 16.dp)
        ) {

            // 输入框
            TodoInputText(
                text = text,
                onTextChange = onTextChange,
                modifier = Modifier
                    .weight(1f)
                    .padding(end = 8.dp),
                onItemAction = submit
            )
            // 按钮
            TodoEditButton(
                onClick = submit, text = "Add",
                modifier = Modifier.align(Alignment.CenterVertically),
                enabled = text.isNotBlank()
            )

        }

        if (iconsVisible) {
            AnimatedIconRow(
                icon = icon,
                onIconChange = onIconChange,
                modifier = Modifier.padding(top = 8.dp),
                visible = true
            )
        } else {
            Spacer(modifier = Modifier.height(16.dp))
        }
    }

}
